Гранью (border, verge, brink) br строки S называется любой собственный префикс этой
строки, равный суффиксу S.
Строка S = abaababaabaab имеет две грани (не пустые) - ab и abaab. Строка S = abaabaab также имеет две грани – ab и abaab, но вторая грань – перекрывающаяся. Строка длины n из повторяющегося символа, например aaaaaaaa (или a8), имеет n –
1 грань. Для S = a8 это
грани: a, aa, aaa, aaaa, aaaaa, aaaaaa, aaaaaaa.
Понятие "собственный
префикс" исключает грань, совпадающую с самой строкой.
Длина грани – это количество
символов в ней.
Сделаем обобщение задачи. Пусть
необходимо вычислить значения наибольших граней для всех подстрок S[1..i] (i
= 1..n) и сохранить их в массиве
br[1..n].
Найдите наибольшее значение грани
в массиве наибольших граней br для всех подстрок S.
Вход. Дана
строка S (|S| ≤ 106).
Выход. В единственной строке вывести
ответ поставленной задачи.
Пример входа
abaabaab
Пример выхода
5
строки – префикс-функция
Построим для строки S в массиве p
префикс-функцию. Для решения задачи достаточно найти максимальное значение
среди всех p[i] (0 ≤ i < n).
Входная строка s содержит не более MAX =
1000010 символов.
Префикс-функцию строки s сохраняем в векторе
p.
#define MAX 1000010
char s[MAX];
vector<int>
p;
Строим префикс-функцию для строки
s длины n при помощи функции MaxBorderArray. Вычисляем длину наибольшей
грани среди всех граней подстрок S в переменной res.
gets(s); n =
strlen(s);
p = MaxBorderArray(s);
for(i = 1; i < n; i++)
if (res <
p[i]) res = p[i];
printf("%d\n",res);